package com.gitee.xqxyxchy.crypto.impl;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

import org.bouncycastle.util.encoders.Hex;

import com.gitee.xqxyxchy.crypto.CryptoParam;
import com.gitee.xqxyxchy.crypto.ICryptoService;
import com.gitee.xqxyxchy.crypto.ParamKey;

public class DesCrypto implements ICryptoService {

	private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
	private static final String KEY_ALGORITHM = "DES";
	private static final String DEFAULT_ALGORITHMS = "DES/CBC/PKCS5Padding";

	@Override
	public String encrypt(String originData, CryptoParam... params) {
		try {
			String algorithms = CryptoParam.Builder.create().get(ParamKey.ALGORITHMS.getKey(), DEFAULT_ALGORITHMS,
					params);
			String privateKey = CryptoParam.Builder.create().get(ParamKey.PRIVATE_KEY.getKey(), params);
			String iv = CryptoParam.Builder.create().get(ParamKey.IV_KEY.getKey(), params);
			Cipher cipher = Cipher.getInstance(algorithms, new org.bouncycastle.jce.provider.BouncyCastleProvider());
			DESKeySpec desKeySpec = new DESKeySpec(privateKey.getBytes(DEFAULT_CHARSET));
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
			SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
			IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(DEFAULT_CHARSET));
			cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
			return new String(Hex.toHexString(cipher.doFinal(originData.getBytes(DEFAULT_CHARSET))));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public String decrypt(String encryptedData, CryptoParam... params) {
		try {
			String algorithms = CryptoParam.Builder.create().get(ParamKey.ALGORITHMS.getKey(), DEFAULT_ALGORITHMS,
					params);
			String privateKey = CryptoParam.Builder.create().get(ParamKey.PRIVATE_KEY.getKey(), params);
			String iv = CryptoParam.Builder.create().get(ParamKey.IV_KEY.getKey(), params);
			byte[] decode = Hex.decode(encryptedData);
			Cipher cipher = Cipher.getInstance(algorithms, new org.bouncycastle.jce.provider.BouncyCastleProvider());
			DESKeySpec desKeySpec = new DESKeySpec(privateKey.getBytes(DEFAULT_CHARSET));
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
			SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
			IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(DEFAULT_CHARSET));
			cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
			byte[] retByte = cipher.doFinal(decode);
			return new String(retByte, DEFAULT_CHARSET);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}
